const throttle = (fn: Function, duration: number) => {
  let timer: ReturnType<typeof setTimeout> | undefined = undefined
  let remaining = 0
  return (...args: any[]) => {
    let now = Date.now()  // 当前时间
    if (remaining === 0 || now - remaining > duration) {
      fn(...args)
      remaining = now
    } else {
      clearTimeout(timer)
      timer = setTimeout(() => {
        fn(...args)
        remaining = 0
      }, now - remaining)
    }
  }
}



//gpt 优秀代码
type ThrottleOptions = {
  leading?: boolean,  // 是否执行第一次函数调用
  trailing?: boolean,  // 是否执行最后一次函数调用
}

const throttle2 = <T extends (...args: any[]) => any>(
  fn: T, 
  wait: number,
  options: ThrottleOptions = {}
) => {
  let timerId: number | undefined = undefined;
  let lastArgs: any[] | undefined = undefined;
  let lastCallTime = 0;
  let leading = options.leading ?? true;
  let trailing = options.trailing ?? true;

  const clearTimer = () => {
    if (timerId) {
      cancelAnimationFrame(timerId);
      timerId = undefined;
    }
  };

  const invokeFn = (time: number) => {
    clearTimer();
    fn(...lastArgs!);
    lastCallTime = time;
  };

  return function throttledFn(...args: Parameters<T>) {
    const time = Date.now();
    lastArgs = args;

    if (leading && lastCallTime === 0) {
      invokeFn(time);
    } else if (trailing && time - lastCallTime > wait) {
      invokeFn(time);
    } else {
      clearTimer();
      timerId = requestAnimationFrame(() => {
        throttledFn(...(lastArgs as Parameters<T>));
      });
    }
  };
};